home *** CD-ROM | disk | FTP | other *** search
- #pragma inline
-
- #include "xmsmgr.hpp"
-
- xmsmgr::xmsmgr()
- {
- xmsaddr = 0L; // assume not present at first
- installed = FALSE;
- largest_free_xm = 0;
- total_free_xm = 0;
- errcode = 0;
- // this one is tricky
- // look at the pointer cast carefully
-
- list_handles = (unsigned (*)[128][2])new unsigned[128*2];
- int i;
- for (i = 0; i < 128; ++i)
- (*list_handles)[i][0] = -1;
- asm { // test for the HIMEM.SYS driver
- mov ax,4300h // 4300h = get install state
- int 2fh // call driver
- cmp al,80h // AL has 80h if present
- je is_installed
- jmp not_installed
- }
- is_installed:
- long driver = xmsaddr;
-
- asm {
- mov ax,4310h // request driver address
- int 2fh // call driver
- mov word ptr driver,bx // driver's far call address
- mov word ptr driver+2,es
- }
- xmsaddr = driver;
- installed = TRUE;
- query_xms();
- if (errcode)
- installed = FALSE;
- return;
-
- not_installed:
- installed = FALSE;
- }
-
- xmsmgr::~xmsmgr()
- {
- long driver = xmsaddr;
- int i;
- for (i = 0; i < 128; ++i) {
- unsigned emb = (*list_handles)[i][0];
- if (emb != -1) { // if emb slot used
- asm {
- mov ah,0ah // free emb
- mov dx,word ptr emb
- call dword ptr driver
- }
- }
- }
- delete list_handles;
- }
-
- void xmsmgr::query_xms()
- {
- long driver = xmsaddr;
- unsigned x_largest = largest_free_xm;
- unsigned x_total = total_free_xm;
-
- asm {
- mov ah,08h
- call dword ptr driver
- or ax,ax
- jz badcall
- mov word ptr x_largest,ax
- mov word ptr x_total,dx
- }
- largest_free_xm = x_largest;
- total_free_xm = x_total;
- return;
- badcall:
- errcode = _BL; // store XMS error state
- }
-
- char* xmsmgr::xmserr()
- {
- static char errstring[80];
-
- strcpy (errstring, "XMS Memory error: ");
- switch (errcode) {
- case notimpl: strcat(errstring,"function not implemented.");
- break;
- case vdisk: strcat(errstring,"VDISK device driver present.");
- break;
- case a20err: strcat(errstring,"A20 error.");
- break;
- case generr: strcat(errstring,"General driver error.");
- break;
- case unrecov: strcat(errstring,"Unrecoverable driver error.");
- break;
- case nohma: strcat(errstring,"HMA does not exist.");
- break;
- case hmainuse: strcat(errstring,"HMA is in use.");
- break;
- case hmamin: strcat(errstring,"Req. less than HMAMIN.");
- break;
- case hmanotal: strcat(errstring,"HMA is not allocated.");
- break;
- case a20enab: strcat(errstring,"A20 line still enabled.");
- break;
- case allxms: strcat(errstring,"All XM is allocated.");
- break;
- case emmhandl: strcat(errstring,"No more EMM handles.");
- break;
- case invhandl: strcat(errstring,"Invalid handle.");
- break;
- case srchandl: strcat(errstring,"Invalid source handle.");
- break;
- case srcoffs: strcat(errstring,"Invalid source offset.");
- break;
- case dsthandl: strcat(errstring,"Invalid destination handle.");
- break;
- case dstoffs: strcat(errstring,"Invalid destination offset.");
- break;
- case invlen: strcat(errstring,"Invalid length.");
- break;
- case overlap: strcat(errstring,"Blocks for move overlap.");
- break;
- case parity: strcat(errstring,"XMS parity error.");
- break;
- case notlock: strcat(errstring,"Block is not locked.");
- break;
- case islock: strcat(errstring,"Block is locked.");
- break;
- case lockcnt: strcat(errstring,"Exceeded max locks.");
- break;
- case lockfail: strcat(errstring,"Lock request failed.");
- break;
- case smallumb: strcat(errstring,"A smaller UMB is available.");
- break;
- case noumb: strcat(errstring,"No UMBs available.");
- break;
- case umbseg: strcat(errstring,"Invalid UMB segment number.");
- break;
- case xmshandl: strcat(errstring,"No more XMS handles.");
- break;
- }
- return errstring;
- }
-
- int xmsmgr::alloc_emb (size_t kbytes)
- {
- int i;
-
- for (i = 0; i < 128; ++i) {
- if ((*list_handles)[i][0] == -1) { // unused slot
- long driver = xmsaddr;
- asm {
- mov ah,09h // request allocate
- mov dx,word ptr kbytes
- call dword ptr driver
- or ax,ax
- jz badnews
- jmp goodnews
- }
- goodnews:
- (*list_handles)[i][0] = _DX; // save handle
- (*list_handles)[i][1] = kbytes;
- return i; // return list element, not handle
- badnews:
- errcode = _BL; // save error code
- installed = FALSE; // and signal error
- return -1;
- }
- }
- // If you fall through, no more xms handles in list.
-
- errcode = xmshandl;
- installed = FALSE;
- return -1;
- }
-
-
- void xmsmgr::free_emb (int listnum)
- {
- if (listnum >= 128 || (*list_handles)[listnum][0] == -1)
- return;
- unsigned handle = (*list_handles)[listnum][0];
- long driver = xmsaddr;
- asm {
- mov ah,0ah // request deallocate
- mov dx,word ptr handle
- call dword ptr driver
- }
- }
-
- Boolean xmsmgr::stow (char far* send, size_t listnum,
- unsigned long bytes, unsigned long ofs)
- {
- if (listnum >= 128) {
- errcode = invhandl;
- installed = FALSE;
- return FALSE;
- }
-
- xmsparms pstow;
-
- if (bytes % 2)
- ++bytes;
- pstow.emb_length = bytes;
- pstow.source_handle = 0;
- pstow.source_offset = (long)send;
- pstow.dest_handle = (*list_handles)[listnum][0];
- pstow.dest_offset = ofs;
- long driver = xmsaddr;
- asm {
- push ds // be very careful with DS
- push si
- mov ah,0bh // request EMB MOVE
- lea si,pstow // do SI first, about to lose DS
- mov dx,ss
- mov ds,dx
- call dword ptr driver // driver on stack, so it works
- pop si // be sure to recover these regs
- pop dx
- mov ds,dx
- or ax,ax // test the result
- jz badnews
- jmp goodnews
- }
- goodnews:
- return TRUE;
-
- badnews:
- errcode = _BL; // save error code
- installed = FALSE; // and signal error
- return FALSE;
- }
-
- Boolean xmsmgr::fetch (char far* receive, size_t listnum,
- unsigned long bytes, unsigned long ofs)
- {
- if (listnum >= 128) {
- errcode = invhandl;
- installed = FALSE;
- return FALSE;
- }
-
- xmsparms pfetch;
-
- if (bytes % 2)
- ++bytes;
- pfetch.emb_length = bytes;
- pfetch.dest_handle = 0;
- pfetch.dest_offset = (long)receive;
- pfetch.source_handle = (*list_handles)[listnum][0];
- pfetch.source_offset = ofs;
- long driver = xmsaddr;
- asm {
- push ds // be very careful with DS
- push si
- mov ah,0bh // request EMB MOVE
- lea si,pfetch // do SI first, about to lost DS
- mov dx,ss
- mov ds,dx
- call dword ptr driver // driver on stack, so it works
- pop si // be sure to recover these regs
- pop dx
- mov ds,dx
- or ax,ax // test the result
- jz badnews
- jmp goodnews
- }
- goodnews:
- return TRUE;
-
- badnews:
- errcode = _BL; // save the error code
- installed = FALSE; // and signal error
- return FALSE;
- }
-